package com.ruicar.afs.cloud.account.common.util;

import com.alibaba.fastjson.JSON;
import com.ruicar.afs.cloud.account.dto.tree.RuleTreeDto;
import com.ruicar.afs.cloud.account.dto.tree.RuleTreeExpressDto;
import com.ruicar.afs.cloud.account.enums.rules.RuleItemType;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;


@UtilityClass
@Slf4j
public class RuleConfigUtil {
    private final String BLANK_STR=" ";
    public List<RuleTreeDto> genRuleItemTree(String itemData){
        List<RuleTreeDto> treeDtoList = JSON.parseArray(itemData, RuleTreeDto.class);
        return treeDtoList;
    }

    public String genRuleRunExpress(List<RuleTreeDto> treeDtoList, Map<String,String> atomKeyMapping){

        if(treeDtoList==null||treeDtoList.size()==0){
            return "";
        }
        StringBuffer stringBuffer = new StringBuffer();
        if(RuleItemType.EXPRESS.equals(treeDtoList.get(0).getType())){
            stringBuffer.append(BLANK_STR);
            stringBuffer.append("(");
            for (int i = 0; i < treeDtoList.size(); i++) {
                stringBuffer.append(processItem(i,treeDtoList.get(i),atomKeyMapping));
            }
            stringBuffer.append(")");
        }
        return stringBuffer.toString();
    }



    private String processConditionItem(RuleTreeDto ruleTreeDto,Map<String,String> atomKeyMapping){
        StringBuffer stringBuffer = new StringBuffer();
        if(RuleItemType.EXPRESS.equals(ruleTreeDto.getType())){
            for (int i = 0; i < ruleTreeDto.getRows().size(); i++) {
                stringBuffer.append(processItem(i,ruleTreeDto.getRows().get(i),atomKeyMapping));
            }
        }
        return stringBuffer.toString();
    }




    private String processItem(int index, RuleTreeDto treeDto, Map<String,String> atomKeyMapping){
        StringBuffer stringBuffer = new StringBuffer();
        switch (treeDto.getType()){
            case EXPRESS:{
                if(index>0){
                    stringBuffer.append(BLANK_STR);
                    stringBuffer.append(treeDto.getKey());
                    stringBuffer.append(BLANK_STR);
                }
                testNot(treeDto,stringBuffer);
                if(treeDto.getRows()!=null&&treeDto.getRows().size()>0){
                    for (int i = 0; i < treeDto.getRows().size(); i++) {
                        stringBuffer.append(processItem(i,treeDto.getRows().get(i),atomKeyMapping));
                    }
                }
                break;
            }
            case PLUS:
            case MINUS:
            case TIMES:
            case DIVIDED:
            case AND: {
                if(index>0){
                    stringBuffer.append(BLANK_STR);
                    stringBuffer.append(treeDto.getKey());
                    stringBuffer.append(BLANK_STR);
                }
                stringBuffer.append(processLogicItem(treeDto,atomKeyMapping));
                break;
            }
            default:
                break;

        }
        return stringBuffer.toString();
    }

    private String processLogicItem(RuleTreeDto treeDto, Map<String,String> atomKeyMapping){
        StringBuffer stringBuffer = new StringBuffer();
        testNot(treeDto,stringBuffer);
        stringBuffer.append("(");
        stringBuffer.append(processExpress(treeDto.getExpress(),atomKeyMapping));
        stringBuffer.append(")");
        return stringBuffer.toString();
    }

    private String processExpress(RuleTreeExpressDto express, Map<String,String> atomKeyMapping){
        StringBuffer stringBuffer = new StringBuffer();
        if(express==null||
                express.getLeft()==null||
                express.getLeft().getType()==null||
                express.getOperator()==null||
                StringUtils.isEmpty(express.getOperator().getValue())||
                express.getRight()==null||
                express.getLeft().getType()==null){
            return stringBuffer.toString();
        }
        switch (express.getLeft().getType()){
            case EXPRESS:{
                stringBuffer.append("(");
                stringBuffer.append(processExpress(express.getLeft().getExpress(),atomKeyMapping));
                stringBuffer.append(")");
                break;
            }
            case ATOM:{
                stringBuffer.append(atomKeyMapping.get(express.getLeft().getAtom().getKey()));
                break;
            }
            default:
                break;
        }


        stringBuffer.append(BLANK_STR);
        stringBuffer.append(express.getOperator().getValue());
        stringBuffer.append(BLANK_STR);

        switch (express.getRight().getType()){
            case EXPRESS:{
                stringBuffer.append("(");
                stringBuffer.append(processExpress(express.getRight().getExpress(),atomKeyMapping));
                stringBuffer.append(")");
                break;
            }
            case ATOM:{
                stringBuffer.append(atomKeyMapping.get(express.getRight().getAtom().getKey()));
                break;
            }
            case VALUE:{
                stringBuffer.append(express.getRight().getValue());
            }
            default:
                break;
        }

        return stringBuffer.toString();
    }

    private void testNot(RuleTreeDto treeDto,StringBuffer stringBuffer){
        if(treeDto.isNot()){
            stringBuffer.append("!");
        }
    }
}
